/*
 * File:   latticeSP.hpp
 * Author: gian
 *
 * Created on December 10, 2012, 3:41 PM
 */

#ifndef LATTICESP_HPP
#define LATTICESP_HPP

#include <list>
#include <vector>
#include <stdio.h>


class latticeSP;

FILE *OpenReadDumpFile(char *filename);
FILE *OperWriteDumpFile(char *filename);
void CloseDumpFile(FILE *str);

class nodeSP {
  public:
    friend class latticeSP;


    nodeSP();

    nodeSP(const nodeSP & orig);

    ~nodeSP();

    void save(FILE *stream);
    
    void load(FILE *stream);
    
    int & N() {
      return n;
    }

    ;
    double & Theta() {
      return theta;
    }

    ;
    double & Omega() {
      return omega;
    }

    ;

  private:
    int    n;
    double theta;
    double omega;
};


class Box {
  public:
    Box(int xmin,
        int xmax,
        int ymin,
        int ymax,
        int zmin,
        int zmax);

    int xmin();

    int ymin();

    int zmin();

    int xmax();

    int ymax();

    int zmax();

  private:
    int mXmin;
    int mXmax;
    int mYmin;
    int mYmax;
    int mZmin;
    int mZmax;
};


class latticeSP {
  public:
    latticeSP(int nx,
              int ny,
              int nz,
              int n);

    latticeSP(const latticeSP & orig);

    virtual ~latticeSP();

    void init_random(double sigmaPi);

    int save_vtk(const char * filename);

    void save_strings_vtk(const char * filename);
    
    void save(FILE * stream);
    
    void load(FILE * stream);

    nodeSP * first_node() {
      return mNodes;
    }

    ;
    int get_lattice_size() {
      return mNx * mNy * mNz;
    }

    ;
    inline int get_N() {
      return mN;
    }

    ;
    inline int get_Nx() {
      return mNx;
    }

    ;
    inline int get_Ny() {
      return mNy;
    }

    ;
    inline int get_Nz() {
      return mNz;
    }

    ;
    inline nodeSP * operator ()(const int & x,
                                const int & y,
                                const int & z) {
      int xx = (x + mNx) % mNx;
      int yy = (y + mNy) % mNy;
      int zz = (z + mNz) % mNz;

      return mNodes + xx + yy * mNx + zz * mNx * mNy;
    }

    ;
    static void measure_link(nodeSP *              n1,
                             nodeSP *              n2,
                             std::vector<double> & colors);

  private:
    void set_periodic_boundary();

    nodeSP * mNodes;
    int      mNx;
    int      mNy;
    int      mNz;
    int      mN;
};
#endif /* LATTICESP_HPP */


//~ Formatted by Jindent --- http://www.jindent.com
